Typical HAL FMAC use cases for migration ¶
This section provides information about the typical HAL FMAC use cases for migration.
On the FMAC peripheral, both input and output operations can be configured using a variety of modes, including polling, interrupt, DMA, or handled by external peripheral. These modes can be independently selected for input and output, allowing for flexible combinations between FIFO input writing and FIFO output reading (as shown in the table of typical combinations).
In HAL1, these modes were configured using the InputAccess and OutputAccess fields within the FMAC_FilterConfigTypeDef structure.
In HAL2, input data management is performed through the following APIs:
HAL_FMAC_WriteX1()
HAL_FMAC_WriteX1_IT()
HAL_FMAC_WriteX1_DMA()
HAL_FMAC_WriteX1_DMA_Opt()
When delegating input data handling to another peripheral, these WriteX1 APIs are not called directly.
Similarly, output data management uses the APIs:
HAL_FMAC_ReadY()
HAL_FMAC_ReadY_IT()
HAL_FMAC_ReadY_DMA()
HAL_FMAC_ReadY_DMA_Opt()
If output data handling is assigned to another peripheral, the ReadY APIs are not called directly either.
Typical combinations:
|
Input Mode (HAL1) |
Output Mode (HAL1) |
HAL1 Configuration ( InputAccess , OutputAccess ) |
HAL2 Handling (Input / Output APIs) |
|---|---|---|---|
|
Polling |
Polling |
|
|
|
Polling |
Interrupt |
|
|
|
Polling |
DMA |
|
|
|
Interrupt |
Polling |
|
|
|
Interrupt |
Interrupt |
|
|
|
Interrupt |
DMA |
|
|
|
DMA |
Polling |
|
|
|
DMA |
Interrupt |
|
|
|
DMA |
DMA |
|
|
|
External Device (e.g., ADC) |
Any |
|
Do not call Write APIs / Use appropriate Read API or external handling |
|
Any |
External Device |
|
Use appropriate Write API or external handling / Do not call Read APIs |
Use case: FIR or IIR (interrupt input X1, DMA output Y) ¶
This use case shows an FMAC FIR/IIR filter where the X1 input FIFO is filled in interrupt mode and the Y output FIFO is read in DMA mode.
Sequence diagram ¶
Code snippet ¶
|
HAL1 |
HAL2 |
|---|---|
HAL_FMAC_Init(&hfmac)
sFmacConfig.InputBaseAddress = INPUT_BUFFER_BASE;
sFmacConfig.InputBufferSize = INPUT_BUFFER_SIZE;
sFmacConfig.InputThreshold = INPUT_THRESHOLD;
sFmacConfig.CoeffBaseAddress = COEFFICIENT_BUFFER_BASE;
sFmacConfig.CoeffBufferSize = COEFFICIENT_BUFFER_SIZE;
sFmacConfig.OutputBaseAddress = OUTPUT_BUFFER_BASE;
sFmacConfig.OutputBufferSize = OUTPUT_BUFFER_SIZE;
sFmacConfig.OutputThreshold = OUTPUT_THRESHOLD;
sFmacConfig.pCoeffA = aFilterCoeffA;
sFmacConfig.CoeffASize = COEFF_VECTOR_A_SIZE;
sFmacConfig.pCoeffB = aFilterCoeffB;
sFmacConfig.CoeffBSize = COEFF_VECTOR_B_SIZE;
sFmacConfig.Filter = FMAC_FUNC_IIR_DIRECT_FORM_1;
sFmacConfig.InputAccess = FMAC_BUFFER_ACCESS_IT;
sFmacConfig.OutputAccess = FMAC_BUFFER_ACCESS_DMA;
sFmacConfig.Clip = FMAC_CLIP_DISABLED;
sFmacConfig.P = COEFF_VECTOR_B_SIZE;
sFmacConfig.Q = COEFF_VECTOR_A_SIZE;
sFmacConfig.R = GAIN;
HAL_FMAC_FilterConfig(&hfmac, &sFmacConfig);
HAL_FMAC_AppendFilterData(&hfmac, Input);
HAL_FMAC_FilterStart(&hfmac, Output, OutputDataSize);
HAL_FMAC_FilterStop(&hfmac);
HAL_FMAC_DeInit(&gh_fmac);
|
HAL_FMAC_Init(&hfmac, (hal_fmac_t)FMAC);
sFmacConfig.x1_buf.base_half_word = INPUT_BUFFER_BASE;
sFmacConfig.x1_buf.size_half_word = INPUT_BUFFER_SIZE;
sFmacConfig.x2_buf.base_half_word = COEFFICIENT_BUFFER_BASE;
sFmacConfig.x2_buf.size_half_word = COEFFICIENT_BUFFER_SIZE;
sFmacConfig.y_buf.base_half_word = COEFFICIENT_BUFFER_SIZE;
sFmacConfig.y_buf.size_half_word = OUTPUT_BUFFER_BASE;
HAL_FMAC_SetConfig(&hfmac, &sFmacConfig);
data.coeff_a_size_half_word = COEFF_VECTOR_A_SIZE;
data.p_coeff_a = aFilterCoeffA;
data.coeff_b_size_half_word = COEFF_VECTOR_B_SIZE;
data.p_coeff_b = aFilterCoeffB;
HAL_FMAC_PreloadX2(&hfmac, &data);
HAL_FMAC_WriteX1_IT(&hfmac, Input , size_half_word);
HAL_FMAC_ReadY_DMA(&hfmac, Output, OutputDataSize);
HAL_FMAC_StartFilterIIR(&hfmac, COEFF_VECTOR_B_SIZE, COEFF_VECTOR_A_SIZE, GAIN, HAL_FMAC_OPT_IT_FILTER_SATURATION_ERROR);
HAL_FMAC_StopFilter(&hfmac);
HAL_FMAC_DeInit(&gh_fmac);
|
Key changes ¶
HAL2 replaces the HAL1
FMAC_FilterConfigTypeDef(InputAccess/OutputAccess) mode selection with explicit IO APIs (HAL_FMAC_WriteX1_*andHAL_FMAC_ReadY_*).HAL2 uses a clearer split between configuration (
HAL_FMAC_SetConfig()) and runtime processes (Write X1 / Read Y / Start filter).
Use case: FIR or IIR (ADC input X1, DMA output Y) ¶
This use case shows an FMAC FIR/IIR filter where the X1 input FIFO is fed by the ADC (external peripheral) and the Y output FIFO is read in DMA mode.
Sequence diagram ¶
Code snippet ¶
|
HAL1 |
HAL2 |
|---|---|
ADC_MultiModeTypeDef multimode = {0};
ADC_ChannelConfTypeDef sConfig = {0};
/* FMAC WDATA register address (for DMA transfer) */
#define FMAC_WDATA (0x40021418)
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_LEFT;
hadc1.Init.GainCompensation = 0;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_HRTIM_TRG1;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
hadc1.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_1;
sConfig.Offset = REF;
sConfig.OffsetSign = ADC_OFFSET_SIGN_NEGATIVE;
sConfig.OffsetSaturation = DISABLE;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
HAL_FMAC_Init(&hfmac);
sFmacConfig.InputBaseAddress = INPUT_BUFFER_BASE;
sFmacConfig.InputBufferSize = INPUT_BUFFER_SIZE;
sFmacConfig.InputThreshold = INPUT_THRESHOLD;
sFmacConfig.CoeffBaseAddress = COEFFICIENT_BUFFER_BASE;
sFmacConfig.CoeffBufferSize = COEFFICIENT_BUFFER_SIZE;
sFmacConfig.OutputBaseAddress = OUTPUT_BUFFER_BASE;
sFmacConfig.OutputBufferSize = OUTPUT_BUFFER_SIZE;
sFmacConfig.OutputThreshold = OUTPUT_THRESHOLD;
sFmacConfig.pCoeffA = aFilterCoeffA;
sFmacConfig.CoeffASize = COEFF_VECTOR_A_SIZE;
sFmacConfig.pCoeffB = aFilterCoeffB;
sFmacConfig.CoeffBSize = COEFF_VECTOR_B_SIZE;
sFmacConfig.Filter = FMAC_FUNC_IIR_DIRECT_FORM_1;
sFmacConfig.InputAccess = FMAC_BUFFER_ACCESS_NONE;
sFmacConfig.OutputAccess = FMAC_BUFFER_ACCESS_DMA;
sFmacConfig.Clip = FMAC_CLIP_DISABLED;
sFmacConfig.P = COEFF_VECTOR_B_SIZE;
sFmacConfig.Q = COEFF_VECTOR_A_SIZE;
sFmacConfig.R = GAIN;
HAL_FMAC_FilterConfig(&hfmac, &sFmacConfig);
HAL_FMAC_FilterStart(&hfmac, Output, OutputDataSize);
/* Assign FMAC Write Data register (@WDATA) to Fmac_Wdata */
Fmac_Wdata = (uint32_t *) FMAC_WDATA;
/* Start ADC and DMA */
HAL_ADC_Start_DMA(&hadc1, Fmac_Wdata, OUTPUT_BUFFER_SIZE*4);
HAL_FMAC_FilterStop(&hfmac);
HAL_FMAC_DeInit(&gh_fmac);
|
hal_adc_config_t adc_config;
HAL_ADC_Init(&hADC1, HAL_ADC1);
adc_config.resolution = HAL_ADC_RESOLUTION_12_BIT;
adc_config.sampling_mode = HAL_ADC_SAMPLING_MODE_NORMAL;
HAL_ADC_SetConfig(&hADC1, &adc_config);
hal_adc_reg_config_t reg_config;
reg_config.trigger_src = HAL_ADC_REG_TRIG_SOFTWARE_START;
reg_config.trigger_edge = HAL_ADC_REG_TRIG_EDGE_NONE;
reg_config.sequencer_length = 1;
reg_config.sequencer_discont = HAL_ADC_REG_SEQ_DISCONT_DISABLE;
reg_config.continuous = HAL_ADC_REG_CONV_SINGLE;
reg_config.overrun = HAL_ADC_REG_OVR_DATA_OVERWRITTEN;
reg_config.data_transfer = HAL_ADC_REG_DATA_TRANSFER_NONE;
HAL_ADC_REG_SetConfig(&hADC1, ®_config);
hal_adc_channel_config_t adc_channel_config;
adc_channel_config.group = HAL_ADC_GROUP_REGULAR;
adc_channel_config.sequencer_rank = 1;
adc_channel_config.input_mode = HAL_ADC_IN_SINGLE_ENDED;
adc_channel_config.sampling_time = HAL_ADC_SAMPLING_TIME_2CYCLES_5;
HAL_ADC_SetConfigChannel(&hADC1, HAL_ADC_CHANNEL_4, &adc_channel_config);
HAL_FMAC_Init(&hfmac, (hal_fmac_t)FMAC);
sFmacConfig.x1_buf.base_half_word = INPUT_BUFFER_BASE;
sFmacConfig.x1_buf.size_half_word = INPUT_BUFFER_SIZE;
sFmacConfig.x2_buf.base_half_word = COEFFICIENT_BUFFER_BASE;
sFmacConfig.x2_buf.size_half_word = COEFFICIENT_BUFFER_SIZE;
sFmacConfig.y_buf.base_half_word = COEFFICIENT_BUFFER_SIZE;
sFmacConfig.y_buf.size_half_word = OUTPUT_BUFFER_BASE;
HAL_FMAC_SetConfig(&hfmac, &sFmacConfig);
data.coeff_a_size_half_word = COEFF_VECTOR_A_SIZE;
data.p_coeff_a = aFilterCoeffA;
data.coeff_b_size_half_word = COEFF_VECTOR_B_SIZE;
data.p_coeff_b = aFilterCoeffB;
HAL_FMAC_PreloadX2(&hfmac, &data);
/* Obtain the FMAC Write Data register (@WDATA) for ADC */
Fmac_Wdata = HAL_FMAC_GetX1Address(&hfmac);
HAL_FMAC_LockX1WriteAccessForExternPeriph(&hfmac);
HAL_FMAC_ReadY_DMA(&hfmac, Output, OutputDataSize);
HAL_FMAC_StartFilterIIR(&hfmac, COEFF_VECTOR_B_SIZE, COEFF_VECTOR_A_SIZE, GAIN, HAL_FMAC_OPT_IT_FILTER_SATURATION_ERROR);
/* Start ADC and DMA toward FMAC X1 */
HAL_ADC_Start(hadc1);
HAL_ADC_REG_StartConv_DMA(hadc1, (uint8_t const *)Fmac_Wdata, OUTPUT_BUFFER_SIZE*4);
HAL_FMAC_StopFilter(&hfmac);
HAL_FMAC_UnlockX1WriteAccessForExternPeriph(&hfmac);
HAL_FMAC_DeInit(&gh_fmac);
|
Key changes ¶
HAL2 supports external-peripheral feeding of X1 by providing helpers such as
HAL_FMAC_GetX1Address()and explicit lock/unlock of X1 write access for external peripherals.HAL2 keeps the Y DMA read flow explicit through
HAL_FMAC_ReadY_DMA()and completion callbacks.
![@startuml
title: FIR filter with :\n - input/X1 managed with interrupt process \n - output/Y managed with DMA process
participant App as "User application"
participant App
participant "<font color=Black><b>HAL FMAC</b></font>" as FMAC
participant "<font color=green><b>HAL DMA</b></font>" as DMA
participant "FMACx_IRQHandler"
participant "DMAx_IRQHandler"
App -> FMAC : HAL_FMAC_Init()
App <-- FMAC : HAL_OK
group FMAC System initialization: can be called before FMAC HAL initialization
App -[hidden]>FMAC
end
App -> FMAC : HAL_FMAC_FilterConfig()
note right : The interrupt mode configuration for input X1 is carried out in this function by setting FMAC_BUFFER_ACCESS_IT\nin the InputAccess parameter within FMAC_FilterConfigTypeDef structure.\nThe DMA mode configuration for output Y is carried out in this function by setting FMAC_BUFFER_ACCESS_DMA\nin the OutputAccess parameter within FMAC_FilterConfigTypeDef structure.
App <-- FMAC : HAL_OK
App -> FMAC : HAL_FMAC_AppendFilterData()
App <-- FMAC : HAL_OK
App -> FMAC : HAL_FMAC_FilterStart()
App <-- FMAC :HAL_OK
FMAC <- "FMACx_IRQHandler" : HAL_FMAC_IRQHandler()
FMAC --> "FMACx_IRQHandler"
FMAC-> App : HAL_FMAC_GetDataCallback()
FMAC<-- App
"DMAx_IRQHandler" <- : DMAx half complete interrupt
"DMAx_IRQHandler" -> "DMA" : HAL_DMA_IRQHandler()
"DMA" -> FMAC : XferCpltCallback
FMAC-> App : HAL_FMAC_HalfOutputDataReadyCallback()
"DMA" <-- FMAC
"DMAx_IRQHandler" <-- "DMA"
"DMAx_IRQHandler" -->
"DMAx_IRQHandler" <- : DMAx complete interrupt
"DMAx_IRQHandler" -> "DMA" : HAL_DMA_IRQHandler()
"DMA" -> FMAC : XferCpltCallback
FMAC-> App : HAL_FMAC_OutputDataReadyCallback()
"DMA" <-- FMAC
"DMAx_IRQHandler" <-- "DMA"
"DMAx_IRQHandler" -->
App -> FMAC : HAL_FMAC_FilterStop()
App <-- FMAC :HAL_OK
App->FMAC : HAL_FMAC_DeInit()
App<--FMAC
@enduml](../../../../../_images/plantuml-6260dff3d4ab91f4a70d4c036df7b7f9b178a04e.png)
![@startuml
title: FIR filter with :\n - input/X1 managed with interrupt process \n - output/Y managed with DMA process
participant App as "User application"
participant App
participant "<font color=Black><b>HAL FMAC</b></font>" as FMAC
participant "<font color=green><b>HAL DMA</b></font>" as DMA
participant "FMACx_IRQHandler"
participant "DMAx_IRQHandler"
App -> FMAC : HAL_FMAC_Init
App <-- FMAC : HAL_OK
group FMAC System initialization: can be called before FMAC HAL initialization
App -[hidden]>FMAC
end
App -> FMAC : HAL_FMAC_SetConfig
App <-- FMAC :HAL_OK
==Advanced FMAC Configuration (optional)==
App -> FMAC : HAL_FMAC_SetX1FullWatermark
App <-- FMAC :HAL_OK
App -> FMAC : HAL_FMAC_SetYEmptyWatermark
App <-- FMAC :HAL_OK
App -> FMAC : HAL_FMAC_EnableClip
App <-- FMAC :HAL_OK
note over App : Driver state is IDLE,\nUser can start any process or execute any configuration.
== FIR filter with :\n - input/X1 managed with interrupt process \n - output/Y managed with DMA process ==
note over App : Preload of filter coefficients
App -> FMAC : HAL_FMAC_PreloadX2()
App <-- FMAC :HAL_OK
App -> FMAC : HAL_FMAC_WriteX1_IT()
note right : Write data to X1 in interrupt mode
App <-- FMAC :HAL_OK
App -> FMAC : HAL_FMAC_ReadY_DMA()
note right : Read data from Y in DMA mode
App <-- FMAC :HAL_OK
App -> FMAC : HAL_FMAC_StartFilterFIR() or HAL_FMAC_StartFilterIIR()
App <-- FMAC :HAL_OK
FMAC <- "FMACx_IRQHandler" : HAL_FMAC_IRQHandler()
FMAC --> "FMACx_IRQHandler"
FMAC-> App : HAL_FMAC_WriteX1CpltCallback()
FMAC<-- App
note over App : X1 state is IDLE,\nUser can start any Write X1 process.
"DMAx_IRQHandler" <- : DMAx half complete interrupt
"DMAx_IRQHandler" -> "DMA" : HAL_DMA_IRQHandler()
"DMA" -> FMAC : XferCpltCallback
FMAC-> App : HAL_FMAC_ReadYHalfCpltCallback()
"DMA" <-- FMAC
"DMAx_IRQHandler" <-- "DMA"
"DMAx_IRQHandler" -->
"DMAx_IRQHandler" <- : DMAx complete interrupt
"DMAx_IRQHandler" -> "DMA" : HAL_DMA_IRQHandler()
"DMA" -> FMAC : XferCpltCallback
FMAC-> App : HAL_FMAC_ReadYCpltCallback()
"DMA" <-- FMAC
"DMAx_IRQHandler" <-- "DMA"
"DMAx_IRQHandler" -->
note over App : Y state is IDLE,\nUser can start any Read Y process.
App -> FMAC : HAL_FMAC_StopFilter()
App <-- FMAC :HAL_OK
note over App : Filter state is IDLE,\nUser can start any filter or preload process.
App->FMAC : HAL_FMAC_DeInit
App<--FMAC
@enduml](../../../../../_images/plantuml-a7d70147fd2e1ccc257e4bacb5142a272763c583.png)
![@startuml
title: FIR filter with :\n - input/X1 managed by the ADC driver \n - output/Y managed with DMA process
participant App as "User application"
participant App
participant "<font color=Black><b>HAL FMAC</b></font>" as FMAC
participant "<font color=green><b>HAL DMA</b></font>" as DMA
participant "<font color=red><b>HAL ADC</b></font>" as ADC
participant "FMACx_IRQHandler"
participant "DMAx_IRQHandler"
App -> ADC : HAL_ADC_Init
App <-- ADC : HAL_OK
App -> FMAC : HAL_FMAC_Init
App <-- FMAC : HAL_OK
group ADC System initialization: can be called before ADC HAL initialization
App -[hidden]>ADC
end
group FMAC System initialization: can be called before FMAC HAL initialization
App -[hidden]>FMAC
end
App -> FMAC : HAL_FMAC_FilterConfig()
note right : The ADC management configuration for input X1 is carried out in this function by setting FMAC_BUFFER_ACCESS_NONE\nin the InputAccess parameter within FMAC_FilterConfigTypeDef structure.\nThe DMA mode configuration for output Y is carried out in this function by setting FMAC_BUFFER_ACCESS_DMA\nin the OutputAccess parameter within FMAC_FilterConfigTypeDef structure.
App <-- FMAC : HAL_OK
App -> FMAC : HAL_FMAC_AppendFilterData()
App <-- FMAC : HAL_OK
App -> FMAC : HAL_FMAC_FilterStart()
App <-- FMAC :HAL_OK
App -> ADC : HAL_ADC_Start_DMA
note right : Start ADC conversion and store the result in FMAC Write Data register address (@WDATA)
App <-- ADC : HAL_OK
"DMAx_IRQHandler" <- : DMAx half complete interrupt
"DMAx_IRQHandler" -> "DMA" : HAL_DMA_IRQHandler()
"DMA" -> ADC : XferCpltCallback
ADC-> App : HAL_ADC_ConvHalfCpltCallback()
"DMA" <-- ADC
"DMAx_IRQHandler" <-- "DMA"
"DMAx_IRQHandler" -->
"DMAx_IRQHandler" <- : DMAx complete interrupt
"DMAx_IRQHandler" -> "DMA" : HAL_DMA_IRQHandler()
"DMA" -> ADC : XferCpltCallback
ADC-> App : HAL_ADC_ConvCpltCallback()
"DMA" <-- ADC
"DMAx_IRQHandler" <-- "DMA"
"DMAx_IRQHandler" -->
"DMAx_IRQHandler" <- : DMAx half complete interrupt
"DMAx_IRQHandler" -> "DMA" : HAL_DMA_IRQHandler()
"DMA" -> FMAC : XferCpltCallback
FMAC-> App : HAL_FMAC_HalfOutputDataReadyCallback()
"DMA" <-- FMAC
"DMAx_IRQHandler" <-- "DMA"
"DMAx_IRQHandler" -->
"DMAx_IRQHandler" <- : DMAx complete interrupt
"DMAx_IRQHandler" -> "DMA" : HAL_DMA_IRQHandler()
"DMA" -> FMAC : XferCpltCallback
FMAC-> App : HAL_FMAC_OutputDataReadyCallback()
"DMA" <-- FMAC
"DMAx_IRQHandler" <-- "DMA"
"DMAx_IRQHandler" -->
App -> FMAC : HAL_FMAC_FilterStop()
App <-- FMAC :HAL_OK
App->FMAC : HAL_FMAC_DeInit()
App<--FMAC
@enduml](../../../../../_images/plantuml-8e5dad4534d3e3e3eb1920f71ace147ffe1dd9d0.png)
![@startuml
title: FIR filter with :\n - input/X1 managed by the ADC driver \n - output/Y managed with DMA process
participant App as "User application"
participant App
participant "<font color=Black><b>HAL FMAC</b></font>" as FMAC
participant "<font color=green><b>HAL DMA</b></font>" as DMA
participant "<font color=red><b>HAL ADC</b></font>" as ADC
participant "FMACx_IRQHandler"
participant "DMAx_IRQHandler"
App -> ADC : HAL_ADC_Init
App <-- ADC : HAL_OK
App -> FMAC : HAL_FMAC_Init
App <-- FMAC : HAL_OK
group ADC System initialization: can be called before ADC HAL initialization
App -[hidden]>ADC
end
group FMAC System initialization: can be called before FMAC HAL initialization
App -[hidden]>FMAC
end
App -> FMAC : HAL_FMAC_SetConfig
App <-- FMAC :HAL_OK
==Advanced FMAC Configuration (optional)==
App -> FMAC : HAL_FMAC_SetX1FullWatermark
App <-- FMAC :HAL_OK
App -> FMAC : HAL_FMAC_SetYEmptyWatermark
App <-- FMAC :HAL_OK
App -> FMAC : HAL_FMAC_EnableClip
App <-- FMAC :HAL_OK
note over App : Driver state is IDLE,\nUser can start any process or execute any configuration
== FIR filter with :\n - input/X1 managed directly by ADC periph\n - output/Y managed with DMA process ==
note over App : Preload of filter coefficients
App -> FMAC : HAL_FMAC_PreloadX2
App <-- FMAC :HAL_OK
note over App : Get Write Register address.
App -> FMAC : HAL_FMAC_GetX1Address
note right : This function obtains the address of the FMAC Write Data register address (@WDATA), which is then used as the destination\nfor ADC conversion data in the HAL_ADC_REG_StartConv_DMA function.
App <-- FMAC :HAL_OK
App -> FMAC : HAL_FMAC_LockX1WriteAccessForExternPeriph
note right : Update the state of X1 fifo to protect the FMAC driver against accidental\ncalls to the Write X1 APIs in case of input data managed by an external peripheral
App <-- FMAC :HAL_OK
App -> FMAC : HAL_FMAC_ReadY_DMA
note right : Read data from Y in DMA mode
App <-- FMAC :HAL_OK
App -> FMAC : HAL_FMAC_StartFilterFIR or HAL_FMAC_StartFilterIIR
App <-- FMAC :HAL_OK
App -> ADC : HAL_ADC_Start
App <-- ADC : HAL_OK
App -> ADC : HAL_ADC_REG_StartConv_DMA
note right : Start ADC conversion and store the result in FMAC Write Data register address (@WDATA) via DMA\nthe address is recuperated from HAL_FMAC_GetX1Address function
App <-- ADC : HAL_OK
"DMAx_IRQHandler" <- : DMAx half complete interrupt
"DMAx_IRQHandler" -> "DMA" : HAL_DMA_IRQHandler()
"DMA" -> ADC : XferCpltCallback
ADC-> App : HAL_ADC_REG_DataTransferHalfCallback()
"DMA" <-- ADC
"DMAx_IRQHandler" <-- "DMA"
"DMAx_IRQHandler" -->
"DMAx_IRQHandler" <- : DMAx complete interrupt
"DMAx_IRQHandler" -> "DMA" : HAL_DMA_IRQHandler()
"DMA" -> ADC : XferCpltCallback
ADC-> App : HAL_ADC_REG_DataTransferCpltCallback()
"DMA" <-- ADC
"DMAx_IRQHandler" <-- "DMA"
"DMAx_IRQHandler" -->
"DMAx_IRQHandler" <- : DMAx half complete interrupt
"DMAx_IRQHandler" -> "DMA" : HAL_DMA_IRQHandler
"DMA" -> FMAC : XferCpltCallback
FMAC-> App : HAL_FMAC_ReadYHalfCpltCallback
"DMA" <-- FMAC
"DMAx_IRQHandler" <-- "DMA"
"DMAx_IRQHandler" -->
"DMAx_IRQHandler" <- : DMAx complete interrupt
"DMAx_IRQHandler" -> "DMA" : HAL_DMA_IRQHandler
"DMA" -> FMAC : XferCpltCallback
FMAC-> App : HAL_FMAC_ReadYCpltCallback
"DMA" <-- FMAC
"DMAx_IRQHandler" <-- "DMA"
"DMAx_IRQHandler" -->
note over App : Y state is IDLE,\nUser can start any Read Y process.
App -> FMAC : HAL_FMAC_UnlockX1WriteAccessForExternPeriph
note right : Update the state of X1 fifo to unlock the FMAC driver protection that prevents calls to Write X1 APIs
App <-- FMAC :HAL_OK
note over App : X1 state is IDLE,\nUser can start any Read Y process.
App -> FMAC : HAL_FMAC_StopFilter()
App <-- FMAC :HAL_OK
note over App : Filter state is IDLE,\nUser can start any filter or preload process
App->FMAC : HAL_FMAC_DeInit
App<--FMAC
@enduml](../../../../../_images/plantuml-98ae9ee285ebcc178a7fda42d8ce7a22dab7c3b7.png)